home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / setjmps.com / SETJMPS.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1991-04-06  |  3.1 KB  |  78 lines

  1. unit setjmps;
  2. {$F+} {$O-}
  3. { SETJMPS.PAS
  4.  
  5.   This code supports setjmp/jmpback (jmpback is a better name than longjmp)
  6.   in Turbo Pascal 5.x, 6.0  -- and was specially created for use with
  7.   "jumping back" between overlayed units.
  8.  
  9.   setjmp/jmpback are great for dealing with errors and exceptions
  10.   in low-level procedures.
  11.  
  12.   about setjmp:   (adapted from Turbo C++ Library Reference Manual)
  13.  
  14.     setjmp sets up for a nonlocal goto.  When called it stores the
  15.     'task state' in buf and returns 0.  Later, calling jmpback with
  16.     a ret value and this saved 'task state' buffer causes a special
  17.     goto to occurr that makes setjmp appear to have returned AGAIN
  18.     with the ret value passed to jmpback.  (did that make sense?).
  19.  
  20.     In order to support overlays I had to deviate from the C definition
  21.     and pass another parameter to setjmp.  This extra parameter is the
  22.     address of a function (ala procedure variable: localCS) that simply
  23.     returns the Cseg of the unit to jmpback to.  jmpback calls this
  24.     procedure before performing the nonlocal goto--this makes sure an
  25.     overlayed unit is actually in memory before jumping back to it.
  26.       ** Every call to setjmp must pass a function that returns the Cseg
  27.          of the unit that contains the setjmp call.  If setjmp is called
  28.          in several different units, EACH UNIT must have IT'S OWN localCS
  29.          function.
  30.       localCS functions should look something like this:
  31.  
  32.       function localCSfunction:word;
  33.       begin
  34.         localCSfunction := Cseg;
  35.       end;
  36.     (if you didn't understand all that, just look at the example
  37.     files to see how to declare and use the function: localCSfunction).
  38.  
  39.     setjmp must be called before jmpback.  The routine that calls
  40.     setjmp must still be active and cannot have returned before jmpback
  41.     is called.
  42.  
  43.  
  44.   Author: David Stephens,    compuserve 71621,2210.
  45.   april/91
  46.     author's note:  The use of the localCS procedureal variable is clumsy,
  47.                     but is version-independent enough to work in 5.x and 6.0.
  48.                     If you figure out a better way of dealing with the
  49.                     overlayed unit problem than the localCS variable,
  50.                     please let me know.
  51.  
  52.     finally:  I'm giving this code 'as is' to the public domain, to be used
  53.               and abused by the unwashed masses.  Use the code at your own
  54.               risk; I won't accept responsibility for any damages it might
  55.               cause.  I would appreciate being mentioned in any 'improved
  56.               versions' that are derived from this work.
  57.  
  58. }
  59. interface
  60. TYPE
  61.   jmpCSfunc = function:word;
  62.   jmpbuf = record              {no not 'jmp_buf', I'm underbar-impaired}
  63.     localCS : jmpCSfunc;
  64.     ss,sp,bp : word;
  65.     ip,cs : word;
  66.   end;
  67.  
  68. function  setjmp(VAR buf:jmpBuf; CSfunc:jmpCSfunc) : integer;
  69. procedure jmpback(VAR buf:jmpBuf; ret:integer);
  70.  
  71. implementation
  72.  
  73. {$L setjmp}
  74. function  setjmp(VAR buf:jmpBuf; CSfunc:jmpCSfunc) : integer; external;
  75. procedure jmpBack(VAR buf:jmpBuf; ret:integer); external;
  76.  
  77. end.
  78.